package com.lenovo.lcdm.dcm.config.exception;

import com.google.common.base.Throwables;
import com.lenovo.lcdm.common.enums.ResponseMsgEnum;
import com.lenovo.lcdm.common.exception.BusinessException;
import com.lenovo.lcdm.common.exception.InvalidTokenException;
import com.lenovo.lcdm.common.exception.ServiceException;
import com.lenovo.lcdm.common.model.ResponseVo;
import com.lenovo.lcdm.dcm.common.exception.DcmBusinessException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;


/**
 * controller advice
 *
 * @author
 */
@Slf4j
@ResponseStatus(HttpStatus.OK)
@RestControllerAdvice
public class ControllerAdvice {

    /**
     * url param 去除空格
     */
    @InitBinder
    public void initBinder(WebDataBinder webDataBinder) {
        webDataBinder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
    }

//    @ResponseStatus(HttpStatus.FORBIDDEN)
//    @ExceptionHandler(ServiceAuthException.class)
//    public ResponseDto getServiceAuthException(HttpServletRequest req, HttpServletResponse resp, ServiceAuthException e) {
//        log.warn("AdviceController#getServiceAuthException, method:{}, url:{}, raised error:{}", req.getMethod(), req.getRequestURI(), e.getCode());
//
//        resp.setStatus(HttpStatus.UNAUTHORIZED.value());
//        return ResponseDto.error(e.getCode(), e.getMessage());
//    }

    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    @ExceptionHandler(InvalidTokenException.class)
    public ResponseVo getInvalidTokenException(HttpServletRequest req, HttpServletResponse resp, InvalidTokenException e) {
        resp.setStatus(HttpStatus.UNAUTHORIZED.value());
        return ResponseVo.error(ResponseMsgEnum.TOKEN_INVALID);
    }

    @ExceptionHandler(ServiceException.class)
    public ResponseVo getServiceException(HttpServletRequest req, HttpServletResponse resp, ServiceException e) {
        log.warn("AdviceController#getServiceException, method:{}, url:{}, raised error:{}", req.getMethod(), req.getRequestURI(), Throwables.getStackTraceAsString(e));

        resp.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        return ResponseVo.error(e.getCode(), e.getMessage());
    }

    @ExceptionHandler(BusinessException.class)
    public ResponseVo getBusinessException(HttpServletRequest req, HttpServletResponse resp, BusinessException e) {
        log.warn("AdviceController#getBusinessException, method:{}, url:{}, raised error:{}", req.getMethod(), req.getRequestURI(), Throwables.getStackTraceAsString(e));

        resp.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        return ResponseVo.error(e.getCode(), e.getMessage());
    }

    @ExceptionHandler(DcmBusinessException.class)
    public ResponseVo getDcmBusinessException(HttpServletRequest req, HttpServletResponse resp, DcmBusinessException e) {
        log.warn("AdviceController#getBusinessException, method:{}, url:{}, raised error:{}", req.getMethod(), req.getRequestURI(), Throwables.getStackTraceAsString(e));

        resp.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        return ResponseVo.error(e.getCode(), e.getMessage());
    }


//    @ExceptionHandler(DuplicateKeyException.class)
//    public ResponseDto getDuplicateKeyException(HttpServletRequest req, HttpServletResponse resp, DuplicateKeyException e) {
//        log.warn("AdviceController#getDuplicateKeyException, method:{}, url:{}, raised error:{}", req.getMethod(), req.getRequestURI(), Throwables.getStackTraceAsString(e));
//
//        resp.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
//        return ResponseDto.error(ResponseMsgEnum.CONCURRENT_CONFLICT.getCode(), ResponseMsgEnum.CONCURRENT_CONFLICT.getMessage());
//    }
//
//    @ExceptionHandler(ExcelAnalysisException.class)
//    public ResponseDto getEasyExcelException(HttpServletRequest req, HttpServletResponse resp, ExcelAnalysisException e) {
//        log.warn("AdviceController#getEasyExcelException, method:{}, url:{}, raised error:{}", req.getMethod(), req.getRequestURI(), Throwables.getStackTraceAsString(e));
//
//        resp.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
//        // todo jdk17
////        if (e.getCause() instanceof ServiceException serviceException) {
////            return ResponseDto.error(serviceException.getCode(), serviceException.getMessage());
////        }
//        return ResponseDto.error(ResponseMsgEnum.UNKNOWN);
//    }
//
//    @ExceptionHandler(MethodArgumentNotValidException.class)
//    public ResponseDto getMethodArgumentNotValidException(HttpServletRequest req, HttpServletResponse resp, MethodArgumentNotValidException e) {
//        String message = e.getBindingResult().getFieldErrors().stream().map(err ->
//                err.getField().concat(" ").concat(MoreObjects.firstNonNull(err.getDefaultMessage(), StringPool.EMPTY))
//        ).collect(Collectors.joining(";"));
//        log.warn("AdviceController#getMethodArgumentNotValidException, method:{}, url:{}, raised error:{}", req.getMethod(), req.getRequestURI(), message);
//
//        resp.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
//        return ResponseDto.error(ResponseMsgEnum.PARAMETER_ERROR.getCode(), ResponseMsgEnum.PARAMETER_ERROR.formatMsg(message));
//    }


    @ExceptionHandler(Exception.class)
    public ResponseVo getException(HttpServletRequest req, HttpServletResponse resp, Exception e) {
        log.warn("AdviceController#getException, method:{}, url:{}, raised error:{}", req.getMethod(), req.getRequestURI(), Throwables.getStackTraceAsString(e));

        resp.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        return ResponseVo.error(ResponseMsgEnum.UNKNOWN);
    }

//    @ExceptionHandler(BusinessException.class)
//    public ResponseDto getException(HttpServletRequest req, HttpServletResponse resp, BusinessException e) {
//        log.warn("AdviceController#getException, method:{}, url:{}, raised error:{}", req.getMethod(), req.getRequestURI(), Throwables.getStackTraceAsString(e));
//        resp.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
//        return ResponseDto.error(e.getCode(), e.getMessage());
//    }
}
